Imports KanBan.Pgd.Common
Imports NHibernate.Criterion
Imports KanBan.Pgd.Infrastructure.Exceptions
Imports KanBan.Pgd.Domain.Entities
Imports NHibernate
Imports KanBan.Pgd.Domain.ValueObjects
Imports KanBan.Pgd.Security
Imports System.Data.SqlClient
Imports System.Text

Namespace Repositories

    ''' <summary>
    ''' Se encarga de la persistencia de los Usuarios
    ''' </summary>
    ''' <remarks></remarks>
    Public Class UserRepository
        Inherits RepositoryBase(Of User)

        Protected Overrides Sub OnSecurableEntitySaveOrUpdate(ByVal user As User)

            user.Password = Encryption.EncryptMD5(user.Password)
            user.CheckSum = IntegrityHelper(Of User).GetCalculatedCheckSum(user)
            IntegrityHelper(Of User).UpdateMasterCheckuSum(user)

        End Sub

        Protected Overrides Sub OnSecurableEntityGet(ByVal user As User)

            user.IsCorrupted = Not IntegrityHelper(Of User).IsCheckSumValid(user)

        End Sub

        <Obsolete()> _
        Public Sub AddPermissions(ByVal user As User, ByVal permissions As IList(Of Permission))

            Dim session As ISession = NHibernateHelper.GetCurrentSession()
            For Each p As Permission In permissions
                user.IndividualPermissions.Add(p)
            Next

            session.SaveOrUpdate(user)
            session.Flush()

        End Sub

        ''' <summary>
        ''' Obtiene un usuario por su nombre de usuario
        ''' </summary>
        ''' <param name="userName">Nombre de usuario</param>
        ''' <returns>Usuario</returns>
        ''' <remarks></remarks>
        Public Function GetByUserName(ByVal userName As String) As User

            Return MyBase.Get("UserName", userName)

        End Function

        ''' <summary>
        ''' Obtiene un listado todos los permisos del usuario, eliminando los duplicados
        ''' </summary>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function GetAllPermissions(ByVal userId As Guid) As IList(Of Permission)

            Dim user As User = Me.GetById(userId)
            Dim uniquePermissions As New List(Of Permission)

            If user Is Nothing Then
                Return uniquePermissions
            End If

            'Agregamos todos los permisos heredados de los grupos
            For Each g As Group In user.Groups
                For Each gp As GroupPermission In g.GroupPermissions
                    Dim p As Permission = (New ValueObjectRepository(Of Permission)).GetById(gp.Permission.Id)
                    If Not uniquePermissions.Contains(p) Then
                        uniquePermissions.Add(p)
                    End If
                Next
            Next

            'Agregamos los permisos individuales del usuario
            For Each p As Permission In user.IndividualPermissions
                If Not uniquePermissions.Contains(p) Then
                    uniquePermissions.Add(p)
                End If
            Next

            Return uniquePermissions

        End Function

        Public Function GetAllUserIds() As IList(Of Guid)

            Try

                Dim session As ISession = NHibernateHelper.GetCurrentSession()

                Dim ids As IList(Of Guid) = New List(Of Guid)

                Dim hql As String = "select Id from User"
                Dim query As IQuery = session.CreateQuery(hql)

                Dim result As IList(Of Guid) = query.List(Of Guid)()

                If result IsNot Nothing Then
                    ids = result
                End If

                Return ids

            Catch ex As Exception

                Throw New TechnicalException(String.Format("Error while trying to 'GetAllUserIds' - Details: {0}", _
                                                                                            ex.Message), ex.InnerException)

            End Try

        End Function

        Public Function GetUserCompetency(ByVal userId As Guid, ByVal competencyId As Guid) As UserCompetency

            Try

                Dim session As ISession = NHibernateHelper.GetCurrentSession()
                Dim uc As UserCompetency

                Dim hqlQuery As String = "from UserCompetency uc where uc.Competency.Id = :CompetencyId and uc.User.Id = :UserId"

                uc = session.CreateQuery(hqlQuery) _
                            .SetGuid("CompetencyId", competencyId) _
                            .SetGuid("UserId", userId) _
                            .UniqueResult(Of UserCompetency)()

                If uc IsNot Nothing Then session.Refresh(uc)

                Return uc

            Catch ex As Exception

                Throw New TechnicalException(String.Format("Error while trying to 'GetUserCompetency' - Details: {1}", _
                                                                                                ex.Message), ex.InnerException)

            End Try

        End Function

        Public Function GetUserCompetencies(ByVal userId As Guid) As IList(Of UserCompetency)

            Try

                Dim session As ISession = NHibernateHelper.GetCurrentSession()
                Dim entities As IList(Of UserCompetency) = New List(Of UserCompetency)

                Dim hqlQuery As String = "from UserCompetency uc where uc.User.Id = :UserId"

                entities = session.CreateQuery(hqlQuery) _
                            .SetGuid("UserId", userId) _
                            .List(Of UserCompetency)()

                Return entities

            Catch ex As Exception

                Throw New TechnicalException(String.Format("Error while trying to 'GetUserCompetencies' - Details: {0}", _
                                                                                            ex.Message), ex.InnerException)

            End Try

        End Function

        Public Function SaveOrUpdateUserCompetency(ByVal userCompetency As UserCompetency) As UserCompetency

            Try

                Dim session As ISession = NHibernateHelper.GetCurrentSession()

                session.SaveOrUpdate(userCompetency)
                session.Flush()

                Return GetUserCompetency(userCompetency.User.Id, userCompetency.Competency.Id)

            Catch ex As Exception

                Throw New TechnicalException(String.Format("Error while trying to 'SaveOrUpdateUserCompetency' - Details: {1}", _
                                                                                                    ex.Message), ex.InnerException)

            End Try

        End Function

        Public Sub DeleteUserCompetency(ByVal uc As UserCompetency)

            Try

                Dim session As ISession = NHibernateHelper.GetCurrentSession()
                session.Delete(uc)
                session.Flush()

            Catch ex As Exception

                Throw New TechnicalException(String.Format("Error while trying to 'Delete' UserCompetency - Details: {1}", _
                                                                                            ex.Message), ex.InnerException)

            End Try

        End Sub

    End Class

End Namespace
